package djboom.materials.display.elements {
	import djboom.materials.state.Font;

	import org.casalib.display.CasaShape;
	import org.casalib.display.CasaSprite;
	import org.casalib.display.CasaTextField;
	import org.casalib.util.StageReference;

	import flash.display.BlendMode;
	import flash.display.DisplayObject;
	import flash.display.GradientType;
	import flash.events.Event;
	import flash.events.KeyboardEvent;
	import flash.events.MouseEvent;
	import flash.filters.DropShadowFilter;
	import flash.geom.Matrix;
	import flash.text.AntiAliasType;
	import flash.text.TextFieldAutoSize;
	import flash.text.TextFormat;
	import flash.ui.Keyboard;

	/**
	 * .
	 * <br>
	 * 
	 * @author DJ BooM 
	 * @since 22.04.2010
	 * 
	 */

	public class RoundedButton extends CasaSprite {

		// ----------------------------------------------------------------------------
		// Константы класса.
		// ----------------------------------------------------------------------------

		private static const DROPSHADOW_FILTER:DropShadowFilter = new DropShadowFilter(1, -90, 0, 1, 0, 0, 1, 1, false, true);

		private static const TITLE_TFORMAT:TextFormat = new TextFormat(Font.MYRIAD_PRO_COND, 19, 0xffffff, true);

		private static const BUTTON_HEIGHT:int = 34;
		private static const BUTTON_ROUND:int = 6;

		private static const TITLE_X:int = 13;		private static const TITLE_Y:int = 4;

		private static const SCALE_CLICK:Number = 0.95;

		// ----------------------------------------------------------------------------
		// Свойства класса.
		// ----------------------------------------------------------------------------

		private var _gradientMatrix:Matrix = new Matrix();

		private var _titleFieldShadow:CasaTextField;
		private var _titleField:CasaTextField;
		private var _gradientShape:CasaShape;
		private var _gradientBorder:CasaShape;

		private var _initX:int;
		private var _initY:int;

		// ----------------------------------------------------------------------------
		// Конструктор.
		// ----------------------------------------------------------------------------

		public function RoundedButton(titleText:String) {
			super();
			
			this.buttonMode = true;
			this.useHandCursor = true;
			this.mouseChildren = false;
            
			_titleFieldShadow = new CasaTextField();
			_titleFieldShadow.defaultTextFormat = TITLE_TFORMAT;
			_titleFieldShadow.embedFonts = true;
			_titleFieldShadow.selectable = false;
			_titleFieldShadow.autoSize = TextFieldAutoSize.LEFT;            
			_titleFieldShadow.antiAliasType = AntiAliasType.ADVANCED;
			_titleFieldShadow.text = titleText.toUpperCase();
			_titleFieldShadow.x = TITLE_X;
			_titleFieldShadow.y = TITLE_Y;
			_titleFieldShadow.alpha = 0.75;
			_titleFieldShadow.blendMode = BlendMode.OVERLAY;            
			_titleFieldShadow.filters = [DROPSHADOW_FILTER];
            
			_titleField = new CasaTextField();
			_titleField.defaultTextFormat = TITLE_TFORMAT;
			_titleField.embedFonts = true;
			_titleField.selectable = false;
			_titleField.autoSize = TextFieldAutoSize.LEFT;            
			_titleField.antiAliasType = AntiAliasType.ADVANCED;
			_titleField.text = titleText.toUpperCase();
			_titleField.x = TITLE_X;
			_titleField.y = TITLE_Y;
			_titleField.alpha = 0.7;
            
			var widthButton:int = _titleField.textWidth + 30;
			
			_gradientMatrix.createGradientBox(widthButton, BUTTON_HEIGHT / 2, -Math.PI / 2);

			_gradientShape = new CasaShape();
			_gradientShape.graphics.beginGradientFill(GradientType.LINEAR, [0x0c8ed7, 0x33abf1, 0x92d7ff], [1, 1, 1], [0, 230, 250], _gradientMatrix);
			_gradientShape.graphics.drawRoundRectComplex(0, 0, widthButton, BUTTON_HEIGHT / 2, BUTTON_ROUND, BUTTON_ROUND, 0, 0);
            
			_gradientMatrix.createGradientBox(widthButton, BUTTON_HEIGHT / 2, -Math.PI / 2, 0, BUTTON_HEIGHT / 2);
            
			_gradientShape.graphics.beginGradientFill(GradientType.LINEAR, [0x045b8d, 0x0776b6], [1, 1], [40, 255], _gradientMatrix);
			_gradientShape.graphics.drawRoundRectComplex(0, BUTTON_HEIGHT / 2, widthButton, BUTTON_HEIGHT / 2, 0, 0, BUTTON_ROUND, BUTTON_ROUND);
			_gradientShape.graphics.endFill();

			_gradientMatrix.createGradientBox(widthButton, BUTTON_HEIGHT, -Math.PI / 2);
            
			_gradientBorder = new CasaShape();
			_gradientBorder.graphics.lineStyle(2);
			_gradientBorder.graphics.lineGradientStyle(GradientType.LINEAR, [0x004c78, 0x006dad], [1, 1], [0, 255], _gradientMatrix);
			_gradientBorder.graphics.drawRoundRectComplex(0, 0, widthButton, BUTTON_HEIGHT, BUTTON_ROUND, BUTTON_ROUND, BUTTON_ROUND, BUTTON_ROUND);
            
			addChild(_gradientShape);			addChild(_gradientBorder);			addChild(_titleFieldShadow);			addChild(_titleField);
			
			addEventListener(MouseEvent.MOUSE_DOWN, mouseDown);			addEventListener(MouseEvent.MOUSE_UP, mouseUp);
			
			addEventListener(Event.REMOVED_FROM_STAGE, clearContent);
			
			stage.addEventListener(KeyboardEvent.KEY_DOWN, keyDown);
		}	 

		// ----------------------------------------------------------------------------
		// Методы класса.
		// ----------------------------------------------------------------------------

		private function keyDown(event:KeyboardEvent):void {
			if (event.keyCode == Keyboard.SPACE) {
				dispatchEvent(new MouseEvent(MouseEvent.CLICK));
			}
		}

		private function mouseDown(event:MouseEvent):void {
			_initX = this.x;
			_initY = this.y;
			
			this.x = this.x + (this.width - this.width * SCALE_CLICK) * 0.5;
			this.y = this.y + (this.height - this.height * SCALE_CLICK) * 0.5;

			this.scaleX = this.scaleY = SCALE_CLICK;
			
			StageReference.getStage().addEventListener(MouseEvent.MOUSE_UP, captureMouseUp);
		}

		private function mouseUp(event:MouseEvent = null):void {
			this.x = _initX;
			this.y = _initY;

			this.scaleX = this.scaleY = 1;
			
			StageReference.getStage().removeEventListener(MouseEvent.MOUSE_UP, captureMouseUp);
		}

		private function captureMouseUp(event:MouseEvent):void {
			if (event.target == this || this.contains(DisplayObject(event.target))) {
			} else {
				mouseUp();
			}
		}

		private function clearContent(event:Event):void {
			stage.removeEventListener(KeyboardEvent.KEY_DOWN, keyDown);
			
			_gradientMatrix = null;
			
			_gradientBorder.destroy();			_gradientBorder = null;
            
			_gradientShape.destroy();			_gradientShape = null;
            
			_titleField.destroy();			_titleField = null;
            
			_titleFieldShadow.destroy();			_titleFieldShadow = null;
		}
        
		// ----------------------------------------------------------------------------
		// Публичные методы.
		// ----------------------------------------------------------------------------
		
		// ----------------------------------------------------------------------------
        // Публичные свойства.
        // ----------------------------------------------------------------------------
	}
}
